..:: Menu ::.. ..:: Kurs C++ : Pętla krokowa for ::.. ..::Info i Reklamy::..

Do tej pory spotykaliśmy się z sytuacjami, w których należało wykonywać określony kod aż do spełnienia pewnego warunku. Równie często jednak znamy wymaganą ilość „obrotów” pętli jeszcze przed jej rozpoczęciem – chcemy ją podać w kodzie explicite lub obliczyć wcześniej jako wartość zmiennej.
Co wtedy zrobić? Możemy oczywiście użyć odpowiednio spreparowanej pętli while, chociażby w takiej postaci:

int nLicznik = 1;
// wypisanie dziesięciu liczb całkowitych w osobnych linijkach
while (nLicznik <= 10)
{
std::cout << nLicznik << std::endl;
nLicznik++;
}
Powyższe rozwiązanie jest z pewnością poprawne, aczkolwiek istnieje jeszcze lepsze :) W przypadku, gdy znamy z góry liczbę przebiegów pętli, bardziej naturalne staje się użycie instrukcji for (‘dla’). Została ona bowiem stworzona specjalnie na takie okazje i sprawdza się w nich o wiele lepiej niż uniwersalna while. Korzystający z niej ekwiwalent powyższego kodu może wyglądać na przykład tak:
for (int i = 1; i <= 10; i++)
{
std::cout << i << std::endl;
}
Jeżeli uważnie przyjrzysz się obu jego wersjom, z pewnością zdołasz domyśleć się ogólnej zasady działania pętli for. Zanim dokładnie ją wyjaśnię, posłużę się bardziej wyrafinowanym przykładem do jej ilustracji:
// For - pętla krokowa
int Suma(int nLiczba)
{
int nSuma = 0;
for (int i = 1; i <= nLiczba; i++)
nSuma += i;
return nSuma;
}
void main()
{
int nLiczba;
std::cout << "Program oblicza sume od 1 do podanej liczby."
<< std::endl;
std::cout << "Podaj ja: ";
std::cin >> nLiczba;
std::cout << "Suma liczb od 1 do " << nLiczba << " wynosi "
< Suma(nLiczba) << ".";
getch();
}
Mamy zatem kolejny superużyteczny programik do przeanalizowania ;) Bezzwłocznie więc przystąpmy do wykonania tego pożytecznego zadania.
Rzut oka na kod tudzież kompilacja i uruchomienie aplikacji prowadzi do słusznego wniosku, iż przeznaczeniem programu jest obliczanie sumy kilku początkowych liczb naturalnych. Zakres dodawania ustala przy tym sam użytkownik programu. Czynnością sumowania zajmuje się tu odrębna funkcja Suma(), na której skupimy obecnie całą naszą uwagę.
Pierwsza linijka tej funkcji to znana już nam deklaracja zmiennej, połączona z jej inicjalizacją wartością 0. Owa zmienna, nSuma, będzie przechowywać obliczony wynik dodawania, który zostanie zwrócony jako rezultat całej funkcji.
Najbardziej interesującym fragmentem jest występująca dalej pętla for:
for (int i = 1; i <= nLiczba; i++)
nSuma += i;
Wykonuje ona zasadnicze obliczenia: dodaje do zmiennej nSuma kolejne liczby naturalne, zatrzymując się na podanym w funkcji parametrze. Całość odbywa się w następujący, dość prosty sposób:
1.Instrukcja int i = 1 jest wykonywana raz na samym początku. Jak widać, jest to deklaracja i inicjalizacja zmiennej i. Nazywamy ją licznikiem pętli. W kolejnych cyklach będzie ona przyjmować wartości 1, 2, 3, itd.
2. Kod nSuma += i; stanowi blok pętli17 i jest uruchamiany przy każdym jej przebiegu. Skoro zaś licznik i jest po kolei ustawiany na następujące po sobie liczby naturalne, pętla for staje się odpowiednikiem sekwencji instrukcji nSuma += 1; nSuma += 2; nSuma += 3; nSuma += 4; itd.
3.Warunek i <= nLiczba określa górną granicę sumowania. Jego obecność sprawia, że pętla jest wykonywana tylko wtedy, gdy licznik i jest mniejszy lub równy zmiennej nLiczba. Zgadza się to oczywiście z naszym zamysłem.
4. Wreszcie, na koniec każdego cyklu instrukcja i++ powoduje zwiększenie wartości licznika o jeden.
Po dłuższym zastanowieniu nad powyższym opisem można niewątpliwie dojść do wniosku, że nie jest on wcale taki skomplikowany, prawda? :) Zrozumienie go nie powinno nastręczać ci zbyt wielu trudności. Gdyby jednak tak było, przypomnij sobie podaną w tytule nazwę pętli for – krokowa. To całkiem trafne określenie dla tej konstrukcji. Jej zadaniem jest bowiem przebycie pewnej „drogi” (u nas są to liczby od 1 do wartości zmiennej nLiczba) poprzez serię małych kroków i wykonanie po drodze jakichś działań. Klarownie przedstawia to tenże rysunek:

Schemat 5. "Droga" przykładowej pętli for
Mam nadzieję, że teraz nie masz już żadnych kłopotów ze zrozumieniem zasady działania naszego programu.
Przyszedł czas na zaprezentowanie składni omawianej przez nas pętli:
for ([początek]; [warunek]; [cykl])
{
instrukcje
}
Na jej podstawie możemy dogłębnie poznać funkcjonowanie tego ważnego tworu programistycznego. Dowiemy się też, dlaczego konstrukcja for jest uważana za jedną z mocnych stron języka C++.
Zaczniemy od początku, czyli komendy oznaczonej jako… początek :) Wykonuje się ona jeden raz, jeszcze przed wejściem we właściwy krąg pętli. Zazwyczaj umieszczamy tu instrukcję, która ustawia licznik na wartość początkową (może to być połączone z jego deklaracją).
warunek jest sprawdzany przed każdym cyklem instrukcji. Jeżeli nie jest on spełniony, pętla natychmiast kończy się. Zwykle więc wpisujemy w jego miejsce kod porównujący licznik z wartością końcową.
W każdym przebiegu, po wykonaniu instrukcji, pętla uruchamia jeszcze fragment zaznaczony jako cykl. Naturalną jego treścią będzie zatem zwiększenie lub zmniejszenie licznika (w zależności od tego, czy liczymy w górę czy w dół).
Inkrementacja czy dekrementacja nie jest bynajmniej jedyną czynnością, jaką możemy tutaj wykonać na liczniku. Posłużenie się choćby mnożeniem, dzieleniem czy nawet bardziej zaawansowanymi funkcjami jest jak najbardziej dopuszczalne. Wpisując na przykład i *= 2 otrzymamy kolejne potęgi dwójki (2, 4, 8, 16 itd.), i += 10 – wielokrotności dziesięciu, itp. Jest to znaczna przewaga nad wieloma innymi językami programowania, w których liczniki analogicznych pętli mogą się zmieniać jedynie w postępie arytmetycznym (o stałą wartość - niekiedy nawet dopuszczalna jest tu wyłącznie jedynka!).
Elastyczność pętli for polega między innymi na fakcie, iż żaden z trzech podanych w nawiasie „parametrów” nie jest obowiązkowy! Wprawdzie na pierwszy rzut oka obecność każdego wydaje się tu absolutnie niezbędna, jednakże pominięcie któregoś (czasem nawet wszystkich) może mieć swoje logiczne uzasadnienie.
Brak początku lub cyklu powoduje dość przewidywalny skutek – w chwili, gdy miałyby zostać wykonane, program nie podejmie po prostu żadnych akcji. O ile nieobecność instrukcji ustawiającej licznik na wartość początkową jest okolicznością rzadko spotykaną, o tyle pominięcie frazy cykl jest konieczne, jeżeli nie chcemy zmieniać licznika przy każdym przebiegu pętli. Możemy to osiągnąć, umieszczając odpowiedni kod np. wewnątrz zagnieżdżonego bloku if.
Gdy natomiast opuścimy warunek, iteracja nie będzie miała czego weryfikować przy każdym swym „obrocie”, więc zapętli się w nieskończoność. Przerwanie tego błędnego koła będzie możliwe tylko poprzez instrukcję break, którą już za chwilę poznamy bliżej.

W ten oto sposób zawarliśmy bliższą znajomość z pętla krokową for. Nie jest to może łatwa konstrukcja, ale do wielu zastosowań zdaje się być bardzo wygodna. Z tego względu będziemy jej często używali – tak też robią wszyscy programiści C++.

Instrukcje break i continue

Z pętlami związane są jeszcze dwie instrukcje pomocnicze. Nierzadko ułatwiają one rozwiązywanie pewnych problemów, a czasem wręcz są do tego niezbędne. Mowa tu o tytułowych break i continue.
Z instrukcją break (‘przerwij’) spotkaliśmy się już przy okazji konstrukcji switch. Korzystaliśmy z niej, aby zagwarantować wykonanie kodu odpowiadającego tylko jednemu wariantowi case. break powodowała bowiem przerwanie bloku switch i przejście do następnej linijki po nim.
Rola tej instrukcji w kontekście pętli nie zmienia się ani na jotę: jej wystąpienie wewnątrz bloku do, while lub for powoduje dokładnie ten sam efekt. Bez względu na prawdziwość lub nieprawdziwość warunku pętli jest ona błyskawicznie przerywana, a punkt wykonania programu przesuwa się do kolejnego wiersza za nią.
Przy pomocy break możemy teraz nieco poprawić nasz program demonstrujący pętlę do:
// Break – przerwanie pętli
void main()
{
int nLiczba;
do
{
std::cout << "Wprowadz liczbe wieksza od 10" << std::endl;
std::cout << "lub zero, by zakonczyc program: ";
std::cin >> nLiczba;
if (nLiczba == 0) break;
} while (nLiczba <= 10);
std::cout << "Nacisnij dowolny klawisz.";
getch();
}
Mankament niemożności zakończenia aplikacji bez spełnienia jej prośby został tutaj skutecznie usunięty. Mianowicie, gdy wprowadzimy liczbę zero, instrukcja if skieruje program ku komendzie break, która natychmiast zakończy pętlę i uwolni użytkownika od irytującego żądania :)
Podobny skutek (przerwanie pętli po wpisaniu przez użytkownika zera) osiągnęlibyśmy zmieniając warunek pętli tak, by stawał się prawdziwy również wtedy, gdy zmienna nLiczba miałaby wartość 0. W następnym rozdziale dowiemy się, jak poczynić podobną modyfikację.
Instrukcja continue jest używana nieco rzadziej. Gdy program natrafi na nią wewnątrz bloku pętli, wtedy automatycznie kończy bieżący cykl i rozpoczyna nowy przebieg iteracji. Z instrukcji tej korzystamy najczęściej wtedy, kiedy część (zwykle większość) kodu pętli ma być wykonywana tylko pod określonym, dodatkowym warunkiem.

Zakończyliśmy właśnie poznawanie bardzo ważnych elementów języka C++, czyli pętli. Dowiedzieliśmy się o zasadach ich działania, składni oraz przykładowych zastosowaniach. Tych ostatnich będzie nam systematycznie przybywało wraz z postępami w sztuce programowania, gdyż pętle to bardzo intensywnie wykorzystywany mechanizm – nie tylko zresztą w C++.


<--- Wstecz | Dalej --->

   
©Copyright by garUs